This class does the work of using the IMSI
SDK. It connects the application to the application server (inproc or
local), loads drawings, select graphics, draw with the mouse on the
screen. It also controls panning and zooming.
Note: import imsigx40.*. Although it we be nice to import
the TypeLib interface constructed by the Microsoft Type Library
Wizard, some of the interface names conflict with Java names (ie.
Graphics) so we must import them by full Java pathing
(ie. imsigx40.Graphics or
imsigx40.IApplication).
Note: Also Microsoft requires that you use an interface to
access an OLE object, not the class. ie. m_IApp = (imsigx40.IApplication) new
imsigx40.XApplication(). Here
XApplication is a class and must be casted to the IApplication (an
interface) to be used.
import java.awt.*; import java.awt.peer.ComponentPeer; // needed to ge the peer import com.ms.awt.peer.ComponentPeerX; // Microsoft specific peer to get the windows handle. class DrawingCanvas extends java.awt.Canvas { SDKDemo Parent; // IMSI Application COM Interface variable public imsigx40.IApplication m_IApp=null; // these com interfaces are used for drawings public imsigx40.Drawings m_IDrawings=null; public imsigx40.IDrawing m_ITheDrawing=null; // these com interfaces are used for Views public imsigx40.Views m_IViews=null; public imsigx40.View m_ITheView=null; // these com interfaces are used for Graphics public imsigx40.Graphics m_IGraphics=null; public imsigx40.IGraphic m_ITheGraphic=null; public imsigx40.IGraphic m_ISelectedGraphic=null; // these com interfaces are used for Vertices (splines points) public imsigx40.Vertices m_IVertices=null; public imsigx40.IVertex m_ITheVertex=null; private double screenHeight=0.0, screenWidth=0.0, screenLeft=0.0, screenTop=0.0; private double prevX=0.0, prevY=0.0; private double pprevX=0.0, pprevY=0.0; private double currX=0.0, currY=0.0; private int savedColor = 0x000000; // default to black private double viewHeight=0.0, viewWidth=0.0, viewLeft=0.0, viewTop=0.0; protected boolean Zoom = false; protected boolean draggingStarted = false; protected boolean splineStarted = false; protected double xStart = 0.0, yStart = 0.0; protected double ScrollCenterX, ScrollCenterY; // Dead center for scrolling protected double ScrollRangeX, ScrollRangeY; // Scroll range protected int whichButtonDown = 0; protected boolean fromNew = false; protected boolean ClipIt = false; /** constructs the class setting the parent for reference capabitity */ public DrawingCanvas(SDKDemo parent) { super (); Parent = parent; /* This is where we construct the OLE Variable and connect the application to the server. */ try { /* First connect to application server. imsigx40.XApplication must be used to connect to the inproc_server IMSIGX40.DLL. If you wish to connect to the local server TC40.exe use imsigx40.Application Note: It appears to be to early to get the Drawings container: m_IDrawings = (imsigx40.Drawings) m_IApp.getDrawings() at this point in constructor. We must wait until the we first need it in NewDrawing or OpenDrawing , otherwise we get undetermined behavior */ if (m_IApp==null) m_IApp = (imsigx40.IApplication) new imsigx40.XApplication(); } catch (com.ms.com.ComException e) { Parent.StatusBox.setText("System Error connecting to IMSIGX40 OLE"); } catch (Exception e) { Parent.StatusBox.setText("Error connecting to IMSIGX40 OLE"); } } /** NewDrawing sets up a standard default drawing on the screen. It sets the screen size to that of the canvas. **/ public void NewDrawing() { Rectangle Rec = this.bounds(); // drawing surface rectangle String m_fileName; try // all results for COM/OLE come as exceptions so we must set up handling { // Create a Variant for an optional parameter com.ms.com.Variant nParam = new com.ms.com.Variant(); // Set the Variant for no parameter nParam.noParam(); if (m_IApp==null) // we should have connected already but just in case { m_IApp = (imsigx40.IApplication) new imsigx40.XApplication(); m_IDrawings = null; } if (m_IDrawings==null) { // either from reset or first time through, set Drawings container // for some reason trying to set this in init() fails. m_IDrawings = (imsigx40.Drawings) m_IApp.getDrawings(); } // remove previous instance if (m_ITheDrawing != null) m_ITheDrawing.Close(nParam, nParam, nParam); //m_IDrawings = null; m_ITheDrawing = null; m_IViews = null; m_ITheView = null; // method -- imsigx40.IDrawing Open(java.lang.String, com.ms.com.Variant [optional], com.ms.com.Variant [optional]); m_ITheDrawing = (imsigx40.IDrawing) m_IDrawings.Add(nParam); // display the name of the drawing. Also this is returned by the SDK so is // a good check that it loaded String str = m_ITheDrawing.getName(); Parent.StatusBox.setText("str: " + str); // we now get the views collection for this drawing // method -- imsigx40.Views getViews(); m_IViews = (imsigx40.Views) m_ITheDrawing.getViews(); // add a new view to the views collection for drawing // Class Method -- imsigx40.View Add(com.ms.com.Variant [optional], com.ms.com.Variant [optional]); m_ITheView = (imsigx40.View) m_IViews.Add(nParam, nParam); // now that we have the particular view for the drawing, call the our // repaint procedure to handle the painting using the SDK, we set // the new global coordinates to accomplish the painting screenWidth = Rec.width; screenHeight = Rec.height; screenLeft = 0.0; screenTop = 0.0; viewWidth = 0.0; viewHeight = 0.0; viewLeft = 0.0; viewTop = 0.0; viewZoomBy(0.0); Zoom = false; //repaint(); // calls this classes paint(), which does the drawing local and via SDK nParam.VariantClear(); // clear the Variant fromNew = true; // not a new drawing m_ISelectedGraphic = null; } catch (com.ms.com.ComException e) { Parent.StatusBox.setText("Error connecting to IMSIGX40 OLE"); } catch (Exception e) { Parent.StatusBox.setText("Error in OLE transaction (IMSIGX40)"); } } /** OpenDrawing pops up the OpenDialog dialog box and allow for a choice of files to display on the screen. If a file is choosen, the filename is passed to the SDK where it is loaded and drawn on the canvas. **/ public String OpenDrawing(String fName) { Rectangle Rec = this.bounds(); // drawing surface rectangle String m_fileName; if (fName == null) { // use the Java file open dialog to get and choose available files FileDialog openFileDialog = new java.awt.FileDialog(Parent.frame, "Open Drawing File", FileDialog.LOAD); openFileDialog.setFile ("*.tcw"); openFileDialog.show(); m_fileName = openFileDialog.getFile(); } else m_fileName = fName; // filename passed as method param if (m_fileName != null && m_fileName.indexOf(".tcw") > -1) // load only valid .tcw files { try // all results for COM/OLE come as exceptions so we must set up handling { // set cursor to wait hourglass int currentCursor = Parent.frame.getCursorType(); Parent.frame.setCursor(Frame.WAIT_CURSOR); // Create a Variant for an optional parameter com.ms.com.Variant nParam = new com.ms.com.Variant(); // Set the Variant for no parameter nParam.noParam(); if (m_IApp==null) // we should have connected already but just in case { m_IApp = (imsigx40.IApplication) new imsigx40.XApplication(); m_IDrawings = null; } if (m_IDrawings==null) { // either from reset or first time through, set Drawings container // for some reason trying to set this in init() fails. m_IDrawings = (imsigx40.Drawings) m_IApp.getDrawings(); } // remove previous instance if (m_ITheDrawing != null) m_ITheDrawing.Close(nParam, nParam, nParam); //m_IDrawings = null; m_ITheDrawing = null; m_IViews = null; m_ITheView = null; // method -- imsigx40.IDrawing Open(java.lang.String, com.ms.com.Variant [optional], com.ms.com.Variant [optional]); m_ITheDrawing = (imsigx40.IDrawing) m_IDrawings.Open(m_fileName, nParam, nParam); // display the name of the drawing. Also this is returned by the SDK so is // a good check that it loaded String str = m_ITheDrawing.getName(); Parent.StatusBox.setText("str: " + str); // we now get the views collection for this drawing // method -- imsigx40.Views getViews(); m_IViews = (imsigx40.Views) m_ITheDrawing.getViews(); // add a new view to the views collection for drawing // Class Method -- imsigx40.View Add(com.ms.com.Variant [optional], com.ms.com.Variant [optional]); m_ITheView = (imsigx40.View) m_IViews.Add(nParam, nParam); // now that we have the particular view for the drawing, call the Java // repaint method to handle the painting using the SDK, we set // the new global coordinates to 0's to accomplish the painting viewWidth = 0.0; viewHeight = 0.0; viewLeft = 0.0; viewTop = 0.0; viewZoomBy(0.0); // Specifying 0.0 as the zoom factor redraws... Zoom = true; // reset cursor to wait normal Parent.frame.setCursor(currentCursor); nParam.VariantClear(); // clear the Variant fromNew = true; // not a new drawing m_ISelectedGraphic = null; return m_fileName; } catch (com.ms.com.ComFailException e) // catch failure exception { Parent.StatusBox.setText("Error in OLE transaction (IMSIGX40)"); return "Error in opening: " + m_fileName; } catch (com.ms.com.ComException e) // catch system failure exception { Parent.StatusBox.setText("System Error in OLE transaction (IMSIGX40)"); return "Error in opening: " + m_fileName; } catch (Exception e) // catch the rest of the errors { Parent.StatusBox.setText("Error in OLE transaction (IMSIGX40)"); return "Error in opening: " + m_fileName; } } else return null; } void setButtonDown(int b) { whichButtonDown = b; splineStarted = false; // reset so that spline stops drawing } // Zoom the drawing by 40 points in x and y directions void ZoomPlus() { if (m_ITheDrawing != null) { viewZoomBy(1.414); } } // Zoom the drawing by 40 points in x and y directions void ZoomMinus() { if (m_ITheDrawing != null) { viewZoomBy(0.707); } } /* SCROLLING */ // Verticle Scroll one line up void VScrollLineUp() { if (m_ITheDrawing != null && m_ITheView != null) { double Y = viewTop - (viewHeight/2.0); // Center point of view. double YOrig = Y; Y = Y + (viewHeight/32.0); // scroll in the +Y direction ViewScrollBy(0.0, Y - YOrig); } } // Verticle Scroll down one line void VScrollLineDown() { if (m_ITheDrawing != null && m_ITheView != null) { double Y = viewTop - (viewHeight/2.0); // Center point of view. double YOrig = Y; Y = Y - (viewHeight/32.0); // scroll in the -Y direction ViewScrollBy(0.0, Y - YOrig); } } // Verticle Scroll up one page void VScrollPageUp() { if (m_ITheDrawing != null && m_ITheView != null) { double Y = viewTop - (viewHeight/2.0); // Center point of view. double YOrig = Y; Y = Y + (viewHeight/8.0); // scroll in the +Y direction ViewScrollBy(0.0, Y - YOrig); } } // Verticle Scroll down one page void VScrollPageDown() { if (m_ITheDrawing != null && m_ITheView != null) { double Y = viewTop - (viewHeight/2.0); // Center point of view. double YOrig = Y; Y = Y - (viewHeight/8.0); // scroll in the -Y direction ViewScrollBy(0.0, Y - YOrig); } } // Horizontal Scroll on line up void HScrollLineUp() { if (m_ITheDrawing != null && m_ITheView != null) { double X = viewLeft + (viewWidth/2.0); // Center point of view. double XOrig = X; X = X - (viewWidth/32.0); // scroll in the -X direction ViewScrollBy(X - XOrig, 0.0); } } // Horizontal Scroll on line up void HScrollLineDown() { if (m_ITheDrawing != null && m_ITheView != null) { double X = viewLeft + (viewWidth/2.0); // Center point of view. double XOrig = X; X = X + (viewWidth/32.0); // scroll in the +X direction ViewScrollBy(X - XOrig, 0.0); } } // Horizontal Scroll on line up void HScrollPageUp() { if (m_ITheDrawing != null && m_ITheView != null) { double X = viewLeft + (viewWidth/2.0); // Center point of view. double XOrig = X; X = X - (viewWidth/8.0); // scroll in the -X direction ViewScrollBy(X - XOrig, 0.0); } } // Horizontal Scroll on line up void HScrollPageDown() { if (m_ITheDrawing != null && m_ITheView != null) { double X = viewLeft + (viewWidth/2.0); // Center point of view. double XOrig = X; X = X + (viewWidth/8.0); // scroll in the +X direction ViewScrollBy(X - XOrig, 0.0); } } void viewZoomBy(double Factor) { boolean viewChanged; viewChanged = false; Rectangle rec = bounds(); // get full rectangle of graphics context try { int CompHwnd = 0; // get the Windows handle for the canvas so that IMSI's SDK can draw direct to the window ComponentPeer p = this.getPeer(); if( p != null ) { ComponentPeerX peer = (ComponentPeerX)p; CompHwnd = peer.gethwnd(); // Microsoft specific method } byte b = 0; m_ITheView.putUpdate(b); // delay update until we tell it to m_ITheView.putHWND(CompHwnd); m_ITheView.putMappingMode(1); /* we don't want margins as this will redraw with margins. Using the same screen coordinates this will shrink the screen by margin each redraw. */ b = 0; m_ITheView.putMargins(b); b = 1; // set to same aspect ratio m_ITheView.putFixedAspectRatio (b); boolean zoomIt = false; // See if we need to start over. if ((Factor <= 0.0) || ((viewWidth == 0.0) && (viewHeight == 0.0))) { // Factor <= 0.0 means reset. Otherwise, initial settings. m_ITheView.putScreenLeft(0.0); m_ITheView.putScreenTop(0.0); m_ITheView.putScreenWidth(rec.width); m_ITheView.putScreenHeight(rec.height); //m_ITheView.ZoomToExtents(); // zoom to the largest extents of the drawing. viewLeft = m_ITheView.getViewLeft(); viewTop = m_ITheView.getViewTop(); viewWidth = m_ITheView.getViewWidth(); viewHeight = m_ITheView.getViewHeight(); screenLeft = m_ITheView.getScreenLeft(); screenTop = m_ITheView.getScreenTop(); screenWidth = m_ITheView.getScreenWidth(); screenHeight = m_ITheView.getScreenHeight(); zoomIt = true; viewChanged = true; } if (Factor > 0.0 && Factor != 1.0) { // Keep the center fixed, and change view coordinates. double vCenterX = viewLeft + (viewWidth/2.0); double vCenterY = viewTop - (viewHeight/2.0); viewWidth = viewWidth / Factor; viewHeight = viewHeight / Factor; viewLeft = vCenterX - (viewWidth/2.0); viewTop = vCenterY + (viewHeight/2.0); viewChanged = true; } // Synchronize the view to our new location and zoom. m_ITheView.putViewLeft(viewLeft); m_ITheView.putViewTop(viewTop); m_ITheView.putViewWidth(viewWidth); m_ITheView.putViewHeight(viewHeight); if (zoomIt) m_ITheView.ZoomToExtents(); // zoom to the largest extents of the drawing. repaint(); // Update display. if (viewChanged) updateScrollParams(); // Keep scroll bars in sync. } catch (Exception e) { Parent.StatusBox.setText("Error in OLE transaction (IMSIGX40)"); } } void updateScrollParams() { if (m_ITheDrawing != null) { double X1, Y1, X2, Y2; double Delta1, Delta2; Parent.horizontalScrollbar.setValues(0, 1, 0, 32000); Parent.horizontalScrollbar.setLineIncrement(320); Parent.horizontalScrollbar.setPageIncrement(3200); Parent.verticalScrollbar.setValues(0, 1, 0, 32000); Parent.verticalScrollbar.setLineIncrement(320); Parent.verticalScrollbar.setPageIncrement(3200); // Arbitrary limits if all else fails. ScrollCenterX = 0.0; ScrollCenterY = 0.0; ScrollRangeX = 1.0; ScrollRangeY = 1.0; X1 = viewLeft; Y1 = viewTop - viewHeight; X2 = viewLeft + viewWidth; Y2 = viewTop; try { // Set ScrollCenter to center of drawing's graphics. m_IGraphics = (imsigx40.Graphics) m_ITheDrawing.getGraphics(); //TVarData(varDummy).VError = DISP_E_PARAMNOTFOUND; // Create a Variant for an optional parameter com.ms.com.Variant varDummy = new com.ms.com.Variant(); // Set the Variant for no parameter varDummy.noParam(); // Now we need to find the largest box surrounding our graphics // METHOD: public abstract imsigx40.BoundingBox CalcBoundingBox(com.ms.com.Variant); imsigx40.BoundingBox BBox = (imsigx40.BoundingBox) m_IGraphics.CalcBoundingBox(varDummy); if (BBox.getEmpty() == 1) // true if bounding box empty { // METHOD: public abstract imsigx40.IVertex getMin(); imsigx40.IVertex BoxMin = (imsigx40.IVertex) BBox.getMin(); // METHOD: public abstract imsigx40.IVertex getMax(); imsigx40.IVertex BoxMax = (imsigx40.IVertex) BBox.getMax(); // METHOD: public abstract double getX(); X1 = BoxMin.getX(); Y1 = BoxMin.getY(); X2 = BoxMax.getX(); Y2 = BoxMax.getY(); ScrollCenterX = (X1 + X2)/2.0; ScrollCenterY = (Y1 + Y2)/2.0; // Set min and max for range to include current viewport. if (viewLeft < X1) X1 = viewLeft; if ((viewTop - viewHeight) < Y1) Y1 = viewTop - viewHeight; if ((viewLeft + viewWidth) > X2) X2 = viewLeft + viewWidth; if (viewTop > Y2) Y2 = viewTop; } } catch (Exception e) { } // Set ScrollRange based on largest area included. Delta1 = ScrollCenterX - X1; Delta2 = X2 - ScrollCenterX; if (Delta1 > Delta2) ScrollRangeX = 2.0 * Delta1; else ScrollRangeX = 2.0 * Delta2; Delta1 = ScrollCenterY - Y1; Delta2 = Y2 - ScrollCenterY; if (Delta1 > Delta2) ScrollRangeY = 2.0 *Delta1; else ScrollRangeY = 2.0 * Delta2; ViewSetScrollPos(); } } void ViewScrollBy(double DeltaX, double DeltaY) { viewLeft = viewLeft + DeltaX; viewTop = viewTop + DeltaY; viewZoomBy(1.0); } void ViewSetScrollPos() { double VCenter; int IMax; double DMax, DPos, IPos; if (ScrollRangeX > 0.0) { IMax = Parent.horizontalScrollbar.getMaximum(); DMax = IMax; VCenter = viewLeft + (viewWidth / 2.0); DPos = (DMax / 2.0) + DMax * (VCenter - ScrollCenterX)/ScrollRangeX; if (DPos <= 0.0) IPos = 0; else if (DPos >= DMax) IPos = IMax; else IPos = DPos; // round Parent.horizontalScrollbar.setValue((int)IPos); } if (ScrollRangeY > 0.0) { IMax = Parent.verticalScrollbar.getMaximum(); DMax = IMax; VCenter = viewTop - (viewHeight / 2.0); DPos = (DMax / 2.0) + DMax * (VCenter - ScrollCenterY)/ScrollRangeY; if (DPos < 0.0) IPos = 0; else if (DPos > DMax) IPos = IMax; else IPos = Math.round(DPos); Parent.verticalScrollbar.setValue((int)IPos); } } public boolean mouseDrag (Event event, int x , int y) { // mouse is being dragged accross canvas. This sets dragging to be true so that mouseUp // will know what to do with the mouse points. if (m_ITheDrawing != null) { draggingStarted = true; Parent.StatusBox.setText("mouse: " + x + " " + y); } return true; } public boolean mouseUp(Event evt, int x, int y) { // mouse buton released. If dragging was started then assume this is finish of drag. if (m_ITheDrawing != null && draggingStarted == true && m_ITheView != null) { if (whichButtonDown > 0) { double[] daX = new double[1], daY = new double[1], daxStart = new double[1], dayStart = new double[1]; //double[] daX = new int[1], daY = new int[1], daxStart = new int[1], dayStart = new int[1]; daX[0] = daY[0] = 0.0; daxStart[0] = xStart; dayStart[0] = yStart; m_ITheView.ScreenToView(x, y, daX, daY); // pass in a double and get double array returned m_ITheView.ScreenToView(xStart, yStart, daxStart, dayStart); // pass in a double and get double array returned switch (whichButtonDown) { case Parent.CIRCLECLICK: draggingStarted = false; try // always use the try/catch to catch any returned errors from OLE/SDK { m_IGraphics = (imsigx40.Graphics) m_ITheDrawing.getGraphics(); m_ITheGraphic = m_IGraphics.AddCircleCenterAndPoint(daxStart[0], dayStart[0], 0, daX[0], daY[0], 0); byte b = 1; m_ITheView.putUpdate(b); // delay update until we tell it to //m_ITheView.putHWND(CompHwnd); //m_ITheView.putMappingMode(1); m_IGraphics = null; } catch (Exception e) { Parent.StatusBox.setText("Error in OLE transaction (IMSIGX40)"); } break; case Parent.LINECLICK: try // always use the try/catch to catch any returned errors from OLE/SDK { m_IGraphics = (imsigx40.Graphics) m_ITheDrawing.getGraphics(); m_ITheGraphic = m_IGraphics.AddLineSingle(daxStart[0], dayStart[0], 0, daX[0], daY[0], 0); byte b = 1; m_ITheView.putUpdate(b); // delay update until we tell it to //m_ITheView.putHWND(CompHwnd); //m_ITheView.putMappingMode(1); m_IGraphics = null; } catch (Exception e) { Parent.StatusBox.setText("Error in OLE transaction (IMSIGX40)"); } draggingStarted = false; break; case Parent.SPLINECLICK: try // always use the try/catch to catch any returned errors from OLE/SDK { // create a variant. Used as a placeholder to pass an OLE no parameter com.ms.com.Variant nParam = new com.ms.com.Variant(); // Set the Variant for no parameter nParam.noParam(); com.ms.com.Variant varX = new com.ms.com.Variant(); com.ms.com.Variant varY = new com.ms.com.Variant(); com.ms.com.Variant varZ = new com.ms.com.Variant(); if (!splineStarted) { varX.putDouble(daxStart[0]); varY.putDouble(dayStart[0]); varZ.putDouble(0.0); m_IGraphics = (imsigx40.Graphics) m_ITheDrawing.getGraphics(); m_ITheGraphic = m_IGraphics.AddCurveSpline(daxStart[0], dayStart[0], 0.0); m_IVertices = null; m_IVertices = m_ITheGraphic.getVertices(); varX.putDouble(daX[0]); varY.putDouble(daY[0]); varZ.putDouble(0.0); m_ITheVertex = null; m_ITheVertex = m_IVertices.Add(varX, varY, varZ, nParam, nParam, nParam, nParam, nParam, nParam, nParam, nParam); prevX = xStart; prevY = yStart; // set previous point for spline pprevX = xStart; pprevY = yStart; // set previous point for spline currX = x; currY = y; ClipIt = true; //byte b = 1; //m_ITheView.putUpdate(b); // delay update until we tell it to repaint(); splineStarted = true; } else { byte b = 0; m_ITheView.putUpdate(b); // delay update until we tell it to varX.putDouble(daX[0]); varY.putDouble(daY[0]); varZ.putDouble(0.0); m_ITheVertex = null; m_ITheVertex = m_IVertices.Add(varX, varY, varZ, nParam, nParam, nParam, nParam, nParam, nParam, nParam, nParam); b = 0; m_ITheView.putUpdate(b); // delay update until we tell it to Zoom = false; pprevX = prevX; pprevY = prevY; // set previous point for spline 1st set of point prevX = currX; prevY = currY; // set previous point for spline, second set of points currX = x; currY = y; // third set of points to form clipping rect ClipIt = true; repaint(); splineStarted = true; } } catch (Exception e) { Parent.StatusBox.setText("Error in OLE transaction (IMSIGX40)"); } draggingStarted = false; break; case Parent.STARCLICK: try // always use the try/catch to catch any returned errors from OLE/SDK { } catch (Exception e) { Parent.StatusBox.setText("Error in OLE transaction (IMSIGX40)"); } draggingStarted = false; break; } Zoom = false; } } return true; } public boolean mouseDown(Event evt, int x, int y) { // mouse buton released. If dragging was started the assume this is finish of drag. draggingStarted = false; xStart = x; yStart = y; if (evt.modifiers == Event.META_MASK) { // Create and show as not modal String Str = ""; (new ViewSourceDialog(Parent.frame, false, Str)).show(); return true; } else { if (whichButtonDown == Parent.PICKCLICK && m_ITheView != null && m_ITheDrawing != null) { double dxStart, dyStart; double[] daX = new double[1], daY = new double[1], daxStart = new double[1], dayStart = new double[1]; try // always use the try/catch to catch any returned errors from OLE/SDK { m_ITheView.ScreenToView(xStart, yStart, daxStart, dayStart); // pass in a double and get double array returned com.ms.com.Variant nParam = new com.ms.com.Variant(); // Set the Variant for no parameter nParam.noParam(); com.ms.com.Variant dParam = new com.ms.com.Variant(); dParam.putDouble(0.1); // set the proximity to graphic that you must click to select a graphic // METHOD: public abstract imsigx40.PickResult PickPoint(double, double, com.ms.com.Variant, com.ms.com.Variant, com.ms.com.Variant, com.ms.com.Variant, com.ms.com.Variant, com.ms.com.Variant, com.ms.com.Variant); imsigx40.PickResult m_IThePickedResults = (imsigx40.PickResult) m_ITheView.PickPoint(daxStart[0], dayStart[0], dParam, nParam, nParam, nParam, nParam, nParam, nParam); imsigx40.IGraphic m_IPickGraphic=null; int pickCount = m_IThePickedResults.getCount(); // with PickPoint you will not get more than count of one if (pickCount > 0) { imsigx40.Properties pProp; // First deselect the current selected graphic if any. If we were to Shift Click the object and // test for that here we could do multiple select. We would have to keep a list of the selected // objects for deselection. if (m_ISelectedGraphic != null) { m_IPickGraphic = m_ISelectedGraphic; //m_IPickGraphic.Unselect(); // METHOD: public abstract imsigx40.Properties getProperties(); pProp = (imsigx40.Properties) m_IPickGraphic.getProperties(); // METHOD: public abstract imsigx40.Property getItem(com.ms.com.Variant); com.ms.com.Variant sVar = new com.ms.com.Variant(); sVar.putString("PenColor"); // insert string into variant to get the PenColor property imsigx40.Property m_IThePenColor = (imsigx40.Property) pProp.getItem(sVar); // METHOD: public abstract void putValue(int, com.ms.com.Variant); com.ms.com.Variant iVar = new com.ms.com.Variant(); iVar.putInt(savedColor); m_IThePenColor.putValue(0, iVar); //m_ISelectedGraphic.VariantClear(); m_ISelectedGraphic = null; m_IThePenColor = null; m_IPickGraphic = null; m_IThePenColor = null; pProp = null; } for (int ii=0; ii < pickCount; ii++) { com.ms.com.Variant iVar = new com.ms.com.Variant(); iVar.putInt(ii); // METHOD: public abstract imsigx40.PickEntry getItem(com.ms.com.Variant); imsigx40.PickEntry m_ITheItem = m_IThePickedResults.getItem(iVar); m_IPickGraphic = m_ITheItem.getGraphic(); pProp = m_IPickGraphic.getProperties(); com.ms.com.Variant sVar = new com.ms.com.Variant(); sVar.putString("PenColor"); // METHOD: public abstract imsigx40.Property getItem(com.ms.com.Variant); imsigx40.Property m_IThePenColor = (imsigx40.Property) pProp.getItem(sVar); savedColor = (m_IThePenColor.getValue(0)).getInt(); // METHOD: public abstract void putValue(int, com.ms.com.Variant); com.ms.com.Variant dVar = new com.ms.com.Variant(); dVar.putInt(0xFF00FF); // use Magenta as selected color //m_IPickGraphic.Select(); m_IThePenColor.putValue(0, dVar); m_ISelectedGraphic = null; m_ISelectedGraphic = m_IPickGraphic; // save to global for unpick m_ITheItem = null; m_IThePenColor = null; m_IPickGraphic = null; pProp = null; } } byte b = 1; m_ITheView.putUpdate(b); // delay update until we tell it to m_IGraphics = null; } // this is how we handle an HRESULT of E_FAIL (defined in winerror.h for C++) catch (com.ms.com.ComFailException e) { // don't do anything, we just missed selecting a point. } // this is how we handle an HRESULT of a system error (defined in winerror.h for C++) catch (com.ms.com.ComException e) { Parent.StatusBox.setText("Error in OLE transaction (IMSIGX40)" + e.toString()); } draggingStarted = false; } } return true; } public void reshape(int x, int y, int width, int height) { // Java 1.0 doesn't have a resize event when the screen is resized so we must use // the resize method which is called from layout(). Here we can make sure that // the screen isn't painted SDK code isn't called twice fromNew = false; // not a new drawing Zoom = true; super.reshape(x, y, width, height); } public boolean handleEvent(Event event) { return super.handleEvent(event); } // bypass the regular update which clears the screen, let us do that in paint public void update(java.awt.Graphics g) { paint(g); } /** this is the paint method, here we set up for SDK drawing and call the SDK's refresh() **/ public void paint(java.awt.Graphics g) { if (m_ITheView != null) // make sure we have a view open (also implies and open app, drawing .. { byte b; // used for passing true/false as variant // screen is cleared by method update() first Rectangle rec = bounds(); // get full rectangle of graphics context rec.x = 0; rec.y = 0; g.setColor(Color.white); if (ClipIt == false) g.clearRect(0, 0, rec.width, rec.height); //g.fillRect(0, 0, width, height); g.setColor(getForeground()); // always use the try/catch to catch any returned errors from OLE/SDK try { // allow clipping of small region. This make refresh redraw only clipped region // which ha less flicker than full screen redraw if (ClipIt == true) { int x, y, width, height; double x1 = Math.min(Math.min(currX, prevX), pprevX) - 10; double x2 = Math.max(Math.max(currX, prevX), pprevX) + 10; if ((int)x1 < 0) x1 = 0; if ((int)x2 > bounds().width) x2 = bounds().width; x = (int) x1; width = (int)(x2 - x1); double y1 = Math.min(Math.min(currY, prevY), pprevY) - 10; double y2 = Math.max(Math.max(currY, prevY), pprevY) + 10; if ((int)y1 < 0) y1 = 0; if ((int)y2 > bounds().height) y2 = bounds().height; height = (int)(y2 - y1); y = (int) y1; g.clearRect(x, y, width, height); g.clipRect(x, y, width, height); } ClipIt = false; // don't allow clipping of a region int CompHwnd = 0; // get the Windows handle for the canvas so that IMSI's SDK can draw direct to the window ComponentPeer p = this.getPeer(); if( p != null ) { ComponentPeerX peer = (ComponentPeerX)p; CompHwnd = peer.gethwnd(); // Microsoft specific method } b = 0; m_ITheView.putUpdate(b); // delay update until we tell it to m_ITheView.putHWND(CompHwnd); m_ITheView.putMappingMode(1); /* we don't want margins as this will redraw with margins. Using the same screen coordinates this will shrink the screen by margin each redraw. */ b = 0; m_ITheView.putMargins(b); b = 1; // set to same aspect ratio m_ITheView.putFixedAspectRatio (b); boolean viewChanged = ((viewWidth == 0.0) && (viewHeight == 0.0)); if (viewChanged) { // Initial settings m_ITheView.putScreenLeft(0.0); m_ITheView.putScreenTop(0.0); m_ITheView.putScreenWidth(rec.width); m_ITheView.putScreenHeight(rec.height); m_ITheView.ZoomToExtents(); // m_ITheView.Refresh(); // just call the SDK's Refresh method. } else { // Saved settings m_ITheView.Refresh(); // just call the SDK's Refresh method. } //if ViewChanged then UpdateScrollParams; // screen dimensions screenLeft = m_ITheView.getScreenLeft(); screenTop = m_ITheView.getScreenTop(); screenWidth = m_ITheView.getScreenWidth(); screenHeight = m_ITheView.getScreenHeight(); // drawing/view dimensions viewLeft = m_ITheView.getViewLeft(); viewTop = m_ITheView.getViewTop(); viewWidth = m_ITheView.getViewWidth(); viewHeight = m_ITheView.getViewHeight(); Parent.StatusBox.setText("rectangle: " + screenLeft + " " + screenTop + " " + screenWidth + " " + screenHeight + " *** " + viewLeft + " " + viewTop + " " + viewWidth + " " + viewHeight); } catch (com.ms.com.ComException e) { Parent.StatusBox.setText("Error connecting to IMSIGX40 OLE"); } } } public void displayProperties() { if (m_ITheDrawing != null) { viewPropertiesDialog viewProp = null; //public abstract imsigx40.Properties getProperties(); imsigx40.Properties m_IProperties = (imsigx40.Properties) m_ITheDrawing.getProperties(); int count = m_IProperties.getCount(); com.ms.com.Variant varI = new com.ms.com.Variant(); com.ms.com.Variant varValue = new com.ms.com.Variant(); String pTypeStr = null; String pArrayStr = null; String pValueStr = null; short pType; String pName = null; int nLen=0, tLen=0, vLen=0; Vector vecList = new Vector(); for (int ii=0; ii < count-1; ii++) { // METHOD: public abstract imsigx40.Property getItem(com.ms.com.Variant); varI.putInt(ii); imsigx40.Property m_IItem = (imsigx40.Property) m_IProperties.getItem(varI); pName = m_IItem.getName(); pType = m_IItem.getType(); // METHOD: public abstract com.ms.com.Variant getValue(int); pValueStr = m_IItem.getValue(0).toString(); // check if it is an array by ANDing with VariantArray which produces type of array if ((pType & com.ms.com.Variant.VariantArray) != 0) { pType &= ~com.ms.com.Variant.VariantArray; pArrayStr = "Array of "; } else pArrayStr = ""; switch (pType) { case com.ms.com.Variant.VariantShort: pTypeStr = "Short"; break; case com.ms.com.Variant.VariantInt: pTypeStr = "Integer"; break; case com.ms.com.Variant.VariantFloat: pTypeStr = "Float"; break; case com.ms.com.Variant.VariantDouble: pTypeStr = "Double"; break; case com.ms.com.Variant.VariantDate: pTypeStr = "Date"; break; case com.ms.com.Variant.VariantString: pTypeStr = "String"; break; case com.ms.com.Variant.VariantDispatch: pTypeStr = "Dispatch"; break; case com.ms.com.Variant.VariantError: pTypeStr = "Error"; break; case com.ms.com.Variant.VariantBoolean: pTypeStr = "Boolean"; break; case com.ms.com.Variant.VariantVariant: pTypeStr = "Variant"; break; case com.ms.com.Variant.VariantObject: pTypeStr = "Object"; break; case com.ms.com.Variant.VariantByte: pTypeStr = "Byte"; break; default: pTypeStr = "Unknown"; break; } if (pName.length() > nLen) nLen = pName.length(); if ((pArrayStr + pTypeStr).length() > tLen) tLen = (pArrayStr + pTypeStr).length(); if (pValueStr.length() > vLen) vLen = pValueStr.length(); vecList.addElement(new PropObject(pName, pArrayStr + pTypeStr, pValueStr)); } // display dialog box with properties display in listbox (viewProp = new viewPropertiesDialog(Parent.frame, false, vecList, nLen, tLen, vLen)).show(); } } }